<?php
/**
 * 公共类.
 */

namespace app\admin\service;

use think\Cache;
use think\Exception;
use think\Log;
use think\Request;

/**
 *
 * User: Small Y
 * Date: 2017/03/13
 * @package app\admin\service
 */
class ApiService
{
    /**
     * 参数错误.
     */
    const PARAM_ERROR = 4000003;
    /**
     * 系统错误.
     */
    const SYSTEM_ERROR = 4000004;
    /**
     * 用户信息缓存前缀
     */
    const CACHE_PREFIX = 'zs_login_';
    /**
     * 错误信息.
     *
     * @var array|string
     */
    protected $error;
    /**
     * 返回状态码
     *
     * @var string
     */
    protected $code = 0;
    /**
     * 日志记录类型.
     *
     * @var string
     */
    protected $logType = 'info';
    /**
     * 返回状态信息.
     *
     * @var string
     */
    protected $message = 'fail';
    /**
     * 返回数据(包含code和message).
     *
     * @var array
     */
    protected $returnData = [];
    /**
     * 错误码与错误信息映射.
     *
     * @var array
     */
    protected $mapErrorMsg = [
        self::PARAM_ERROR => '参数错误',
        self::SYSTEM_ERROR => '系统错误',
    ];

    public function __construct()
    {
    }

    /**
     * 获取错误信息.
     *
     * @return array|string
     */
    public function getError()
    {
        return $this->error;
    }

    /**
     * 错误与异常消息处理.
     *
     * @param $e object 抛出异常的对象
     * @param $data array 参数信息
     *
     * @return bool
     */
    protected function _errorMessage($e, $data = [])
    {
        if ($e instanceof Exception) {
            $this->message = $e->getMessage();
            $this->code = $e->getCode();
            //防止系统错误信息直接暴露
            if ('40' !== mb_substr($e->getCode(), 0, 2)) {
                $this->message = $this->mapErrorMsg[self::SYSTEM_ERROR];
                $this->code = self::SYSTEM_ERROR;
            }
            $errorMsg = $e->getMessage().' 在 '.$e->getFile().' '.$e->getLine().' 行'.$e->getTraceAsString();
            $errorMsg .= !empty($data) ? ' 相关参数：'.json_encode($data, JSON_UNESCAPED_UNICODE) : '';
            Log::record($errorMsg, $this->logType);

            return true;
        }

        return false;
    }

    /**
     * @return string
     */
    public static function generateToken()
    {
        //32个字符组成一组随机字符串
        $randChars = getRandChar(32);
        //用三组字符串，进行md5加密
        $timestamp = $_SERVER['REQUEST_TIME_FLOAT'];
        //salt 盐
        $salt = config('token_salt');

        return md5($randChars . $timestamp . $salt);
    }

    /**
     * @param $key
     * @return mixed
     * @throws Exception
     */
    public static function getCurrentTokenVar($key)
    {
        $token = Request::instance()->header('token');
        $vars = Cache::get(self::CACHE_PREFIX.$token);
        if (!$vars) {
            throw new Exception("Token已过期或无效Token",4000004);
        } else {
            if (!is_array($vars)) {
                $vars = json_decode($vars, true);
            }
            if (array_key_exists($key, $vars)) {
                return $vars[$key];
            } else {
                throw new Exception("尝试获取的Token变量并不存在",4000004);
            }
        }
    }

    /**
     * @return mixed
     * @throws Exception
     */
    public static function getCurrentUid()
    {
        $uid = self::getCurrentTokenVar('id');
        return $uid;
    }
}
